package com.ruoyi.by.health.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.by.health.domain.entity.*;
import com.ruoyi.by.health.domain.vo.DeptLotteryRatesVo;
import com.ruoyi.by.health.domain.vo.LotteryOutcomeListVo;
import com.ruoyi.by.health.domain.vo.LotteryOutcomeVo;
import com.ruoyi.by.health.mapper.ByhealthEmpPrizeMapper;
import com.ruoyi.by.health.mapper.ByhealthRulesMapper;
import com.ruoyi.by.health.service.*;
import com.ruoyi.by.health.utils.LotteryUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ByhealthEmpPrizeServiceImpl
 * @Author 张敬琦
 * @Description 添加描述
 * @Date 2024/1/18 23:01
 **/
@Slf4j
@Service
public class ByhealthEmpPrizeServiceImpl implements IByhealthEmpPrizeService {

    @Autowired
    IByhealthEmployeeService employeeService;
    @Autowired
    ByhealthEmpPrizeMapper empPrizeMapper;
    @Autowired
    ByhealthRulesMapper rulesMapper;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private IByhealthPrizeRulesService prizeRulesService;
    @Autowired
    private IByhealthPrizeService prizeService;
    @Autowired
    private IByhealthLotteryOutcomeService lotteryOutcomeService;

    @Override
    public AjaxResult lotteryPrize(Long rulesId) throws CloneNotSupportedException, InterruptedException {
        List<ByhealthLotteryOutcome> lotteryOutcomeArrayList = new ArrayList<>();
        List<LotteryOutcomeVo> smallLotteryOutcome = new ArrayList<>();
        List<LotteryOutcomeVo> bigLotteryOutcome = new ArrayList<>();
        ByhealthRules byhealthRules = rulesMapper.selectByPrimaryKey(rulesId);
        if(1==byhealthRules.getIsOver()){
            lotteryOutcomeArrayList=lotteryOutcomeService.getLotteryOutcomeByRulesId(rulesId);
            if(!CollectionUtils.isEmpty(lotteryOutcomeArrayList)){
                for (ByhealthLotteryOutcome lotteryOutcome : lotteryOutcomeArrayList) {
                    LotteryOutcomeVo lotteryOutcomeVo = new LotteryOutcomeVo();
                    BeanUtils.copyProperties(lotteryOutcome, lotteryOutcomeVo);
                    if (lotteryOutcomeVo.getPrizeType().equals("小区")) {
                        smallLotteryOutcome.add(lotteryOutcomeVo);
                    } else if (lotteryOutcomeVo.getPrizeType().equals("大区")) {
                        bigLotteryOutcome.add(lotteryOutcomeVo);
                    }
                }
                LotteryOutcomeListVo oul = new LotteryOutcomeListVo();
                oul.setBigLotteryOutcome(bigLotteryOutcome);
                oul.setSmallLotteryOutcome(smallLotteryOutcome);
                return AjaxResult.success(oul);
            }
            else {
                return AjaxResult.error("该抽奖已结束");
            }
        }

        ByhealthLotteryOutcome lotteryOutcomeQo = new ByhealthLotteryOutcome();
        lotteryOutcomeQo.setIsAttach(byhealthRules.getIsAttach());
        List<ByhealthEmployee> byhealthEmployees = employeeService.selectEmployeeListNoLottery(lotteryOutcomeQo);
        // 附加轮
        List<ByhealthPrizeRules> prizeRulesList = prizeRulesService.getPrizeRulesList(rulesId);

        List<ByhealthPrize> prizes = prizeService.getByhealthPrizeList();
        Map<Long, ByhealthPrize> prizesMap = prizes.stream().collect(Collectors.toMap(ByhealthPrize::getId, p -> p));

        if(byhealthRules.getIsAttach()==1){
            for (ByhealthPrizeRules prizeRules : prizeRulesList) {
                Integer prizeNumber = prizeRules.getPrizeNumber();
                Long prizeId = prizeRules.getPrizeId();
                Map<String,ByhealthEmployee>  prizeEmployeeMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(byhealthEmployees)) {
                    for (int k = 0; k < 10; k++) {
                        for (int i = 0; i < prizeNumber; i++) {
                            Integer index = getRndInteger(0, byhealthEmployees.size() - 1);
                            ByhealthEmployee employee = byhealthEmployees.get(index);
                            prizeEmployeeMap.put(employee.getEmpCode(), employee);
                            if (byhealthEmployees.size()==prizeNumber){
                                break;
                            }
                        }
                        if (prizeEmployeeMap.size()==prizeNumber){
                            break;
                        }
                    }
                    Set<String> empCodeSet=prizeEmployeeMap.keySet();
                    List<String> empCodeList = new ArrayList<>();
                    empCodeList.addAll(empCodeSet);
                    ByhealthPrize byhealthPrize = prizesMap.get(prizeId);
                    log.info("----prizeId:{}",prizeId);
                    log.info("----prizeNumber:{}",prizeNumber);
                    log.info("----empCodeList:{}",empCodeList.size());
                    Integer loopSize = prizeNumber;
                    if(prizeNumber>=empCodeList.size()){
                        loopSize=empCodeList.size();
                    }
                    for (int i = 0; i < loopSize; i++) {
                        //该员工可以领奖
                        ByhealthLotteryOutcome lotteryOutcome = new ByhealthLotteryOutcome();
                        ByhealthEmployee employee = prizeEmployeeMap.get(empCodeList.get(i));
                        lotteryOutcome.setEmpId(employee.getEmpId());
                        lotteryOutcome.setPrizeId(prizeId);
                        lotteryOutcome.setRulesId(rulesId);
                        lotteryOutcome.setPrizeName(byhealthPrize.getPrizeName());
                        lotteryOutcome.setPrizeType(byhealthPrize.getPrizeType());
                        lotteryOutcome.setImageUrl(byhealthPrize.getImageUrl());
                        lotteryOutcome.setPrizeUrl(byhealthPrize.getPrizeUrl());
                        lotteryOutcome.setEmpCode(employee.getEmpCode());
                        lotteryOutcome.setEmpName(employee.getEmpName());
                        lotteryOutcome.setDeptId(employee.getDeptId());
                        lotteryOutcome.setDeptName(employee.getDeptName());
                        lotteryOutcome.setBuId(employee.getBuId());
                        lotteryOutcome.setBuName(employee.getBuName());
                        lotteryOutcome.setIsAttach(byhealthRules.getIsAttach());
                        lotteryOutcome.setRulesName(byhealthRules.getRulesName());
                        //empPrizeLogMap.put(employee.getEmpId(), lotteryOutcome);
                        lotteryOutcomeArrayList.add(lotteryOutcome);

                    }
                }

            }
        }
        else {


            Map<Long, List<ByhealthEmployee>> map = byhealthEmployees.stream().collect(Collectors.groupingBy(ByhealthEmployee::getBuId));
            Map<Long, List<ByhealthPrizeRules>> prizeRulesMap = prizeRulesList.stream().collect(Collectors.groupingBy(ByhealthPrizeRules::getBuId));
            for (Long buId : prizeRulesMap.keySet()) {
                Map<String, ByhealthEmployee> prizeEmployeeMap = new HashMap<>();
                List<ByhealthPrizeRules> byhealthPrizeRulesList = prizeRulesMap.get(buId);
                List<ByhealthEmployee> lists = map.get(buId);
                Integer prizeNumber = 0;
                List<Long> prizeIds = new ArrayList<>();
                for (ByhealthPrizeRules byhealthPrizeRules : byhealthPrizeRulesList) {
                    prizeNumber = prizeNumber + byhealthPrizeRules.getPrizeNumber();
                    for (int i = 0; i < byhealthPrizeRules.getPrizeNumber(); i++) {
                        prizeIds.add(byhealthPrizeRules.getPrizeId());
                    }
                }
                log.info("----buId:{}",buId);
                log.info("----prizeNumber:{}",prizeNumber);
                log.info("----prizeIds.size:{}",prizeIds.size());
                if (!CollectionUtils.isEmpty(lists)) {
                    for (int k = 0; k < 50; k++) {
                        for (int i = 0; i < prizeNumber; i++) {
                            Integer index = getRndInteger(0, lists.size() - 1);
                            ByhealthEmployee employee = lists.get(index);
                            prizeEmployeeMap.put(employee.getEmpCode(), employee);
                            if (prizeEmployeeMap.size() == prizeNumber) {
                                break;
                            }
                        }
                        if (prizeEmployeeMap.size() == prizeNumber) {
                            break;
                        }
                    }

                }

                Set<String> empCodeSet = prizeEmployeeMap.keySet();
                List<String> empCodeList = new ArrayList<>();
                empCodeList.addAll(empCodeSet);
                log.info("----empCodeList.size:{}",empCodeList.size());
                Integer loopSize = prizeNumber;
                if (prizeNumber >= empCodeList.size()) {
                    loopSize = empCodeList.size();
                }
                log.info("----loopSize:{}",loopSize);

                for (int i = 0; i < loopSize; i++) {
                    Long prizeId = prizeIds.get(i);
                    ByhealthPrize byhealthPrize = prizesMap.get(prizeId);
                    ByhealthLotteryOutcome lotteryOutcome = new ByhealthLotteryOutcome();
                    ByhealthEmployee employee = prizeEmployeeMap.get(empCodeList.get(i));
                    lotteryOutcome.setEmpId(employee.getEmpId());
                    lotteryOutcome.setPrizeId(prizeId);
                    lotteryOutcome.setRulesId(rulesId);
                    lotteryOutcome.setPrizeName(byhealthPrize.getPrizeName());
                    lotteryOutcome.setPrizeType(byhealthPrize.getPrizeType());
                    lotteryOutcome.setImageUrl(byhealthPrize.getImageUrl());
                    lotteryOutcome.setPrizeUrl(byhealthPrize.getPrizeUrl());
                    lotteryOutcome.setEmpCode(employee.getEmpCode());
                    lotteryOutcome.setEmpName(employee.getEmpName());
                    lotteryOutcome.setDeptId(employee.getDeptId());
                    lotteryOutcome.setDeptName(employee.getDeptName());
                    lotteryOutcome.setBuId(employee.getBuId());
                    lotteryOutcome.setBuName(employee.getBuName());
                    lotteryOutcome.setIsAttach(byhealthRules.getIsAttach());
                    lotteryOutcome.setRulesName(byhealthRules.getRulesName());
                    //empPrizeLogMap.put(employee.getEmpId(), lotteryOutcome);
                    lotteryOutcomeArrayList.add(lotteryOutcome);

                }
            }
        }
        //log.info("---------------------------------lotteryOutcomeArrayList：{}",JSON.toJSONString(lotteryOutcomeArrayList));
        Collections.shuffle(lotteryOutcomeArrayList);
        List<ByhealthLotteryOutcome> lotteryOutcomeArrayListNew = new ArrayList<>();
        for (ByhealthLotteryOutcome lotteryOutcome : lotteryOutcomeArrayList) {
            lotteryOutcomeArrayListNew.add(lotteryOutcome.clone());
        }
        List<ByhealthLotteryOutcome> bigList = new ArrayList<>();
        List<ByhealthLotteryOutcome> smallList = new ArrayList<>();
        for (ByhealthLotteryOutcome lotteryOutcome : lotteryOutcomeArrayListNew) {
            if (lotteryOutcome.getPrizeId()==1||lotteryOutcome.getPrizeId()==2) {
                bigList.add(lotteryOutcome);
            }else {
                smallList.add(lotteryOutcome);
            }
        }

        lotteryOutcomeService.batchInsertLotteryOutcome(smallList);
        lotteryOutcomeService.batchInsertBigLotteryOutcome(bigList);
        byhealthRules.setIsOver(1);
        rulesMapper.updateByPrimaryKeySelective(byhealthRules);
        for (ByhealthLotteryOutcome lotteryOutcome : lotteryOutcomeArrayList) {
            LotteryOutcomeVo lotteryOutcomeVo = new LotteryOutcomeVo();
            BeanUtils.copyProperties(lotteryOutcome, lotteryOutcomeVo);
           if (lotteryOutcomeVo.getPrizeType().equals("大区")) {
                bigLotteryOutcome.add(lotteryOutcomeVo);
            }else{
                 smallLotteryOutcome.add(lotteryOutcomeVo);
            }
        }
        LotteryOutcomeListVo oul = new LotteryOutcomeListVo();
        oul.setBigLotteryOutcome(bigLotteryOutcome);
        //Collections.shuffle(smallLotteryOutcome);
        oul.setSmallLotteryOutcome( smallLotteryOutcome);
        return AjaxResult.success(oul);
    }
    private Integer getRndInteger(int x, int y) {
        int num = -1;
        //说明：两个数在合法范围内，并不限制输入的数哪个更大一些
        if (x < 0 || y < 0) {
            return num;
        } else {
            int max = Math.max(x, y);
            int min = Math.min(x, y);
            //求差
            int mid = max - min;
            //产生随机数
            num = (int) (Math.random() * (mid + 1)) + min;
        }
        return num;
    }

}
